import { Entity } from "../../../../../Core/Module/Entity/Entity";
import { Log } from "../../../../../Core/Module/Log/Log";
import { ErrorCore } from "../../../../../Core/Module/Network/ErrorCore";
import { Exception } from "../../../../../Core/Object/Exception";
import { GetTypeOf, Type } from "../../../../../Decorator/Decorator";
import { IMActorHandler } from "../../../../Model/Server/Module/Actor/IMActorHandler";
import { ActorResponse } from "../../../../Model/Share/Module/ActorLocation/ActorResponse";
import { IActorLocationRequest, IActorLocationResponse } from "../../../../Model/Share/Module/ActorLocation/IActorLocationMessage";
import { ActorHandleHelper } from "../Actor/ActorHandleHelper";

export abstract class AMActorLocationRpcHandler<E extends Entity, TActorLocationRequest extends IActorLocationRequest, TActorLocationResponse extends IActorLocationResponse> extends IMActorHandler {

    protected abstract Run(unit: E, request: TActorLocationRequest, response: TActorLocationResponse);

    public async Handle(entity: Entity, fromProcess: number, actorMessage: Object): Promise<ActorResponse> {
        try {
            let request = actorMessage as TActorLocationRequest;
            if (!request) {
                // Log.Error(`消息类型转换错误: ${GetTypeOf(actorMessage)} to ${GetTypeOf(Request)}`);
                return;
            }
            let ee = entity as E;
            if (!ee) {
                // Log.Error(`Actor类型转换错误: ${GetTypeOf(entity)} to ${GetTypeOf(E)} -- ${GetTypeOf(Request)}`);
                return;
            }
            let rpcId = request.RpcId;
            let response = new ActorResponse();
            try {
                await this.Run(ee, request, response as TActorLocationResponse);
            } catch (e) {
                Log.Error(e);
                response.Error = ErrorCore.ERR_RpcFail;
                response.Message = e.toString();
            }
            response.RpcId = rpcId;
            ActorHandleHelper.Reply(fromProcess, response);
        } catch (e) {
            throw new Exception(`解释消息失败: ${GetTypeOf(actorMessage)} ${e}`);
        }
    }

    public override GetRequestType(): Type {
        return GetTypeOf(this._RequestType);
    }

    public override GetResponseType(): Type {
        return GetTypeOf(this._ResposeType);
    }

}